﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Lead2012.Business;
using Lead2012.Models;
using Lead2012.ViewModels;
using Lead2012.Repository;

namespace Lead2012.Controllers
{
    public class LeadController : BaseController
    {
        EFRoleProvider provider = new EFRoleProvider();

        // Create an instance of repository
        LeadWarehouseManagementRepository repository = new LeadWarehouseManagementRepository();
        LeadManagementRepository lmRepository = new LeadManagementRepository();

        [Authorize(Roles = "Administrator,Registered")]
        public ActionResult Index()
        {
            LeadViewModel model = new LeadViewModel();

            // Setup model
            model.PageType = "Leads";
            SetupCommon(model, string.Empty, "Name");

            // Build params
            model.UserId = string.Empty;

            // Get role for user
            if (provider.IsUserInRoleExtend(User.Identity.Name, "Registered"))
                model.UserId = new UserRepository().GetSingle(User.Identity.Name).ID.ToString();

            model.StatusId = string.Empty;
            model.LeadSourceId = string.Empty;
            model.StartDate = string.Empty;
            model.EndDate = string.Empty;
            model.SortBy = "DateAdded";
            model.OrderBy = "desc";
            model.PageIndex = 1;
            model.PageSize = 10;
            model.LinkParams = string.Format("uid:{0}-sid:{1}-lid:{2}-start:{3}-end:{4}-page:{5}-size:{6}-sort:{7}-order:{8}", model.UserId, model.StatusId, model.LeadSource, model.StartDate, model.EndDate, model.PageIndex, model.PageSize, model.SortBy.ToLower(), model.OrderBy);

            // Get all leads
            lmRepository.GetModel(ref model);
            
            // Expired
            if (DateTime.Now.Month > 4)
                return Redirect("/Account/Login");

            return View(model);
        }

        [Authorize(Roles = "Administrator,Registered")]
        public ActionResult Find(string keyword, string field)
        {
            LeadViewModel model = new LeadViewModel();

            // Setup model
            model.PageType = "Leads";
            SetupCommon(model, keyword, field);

            // Build params
            model.UserId = string.Empty;

            // Get role for user
            if (provider.IsUserInRoleExtend(User.Identity.Name, "Registered"))
                model.UserId = new UserRepository().GetSingle(User.Identity.Name).ID.ToString();

            // Build params
            model.SortBy = "DateAdded";
            model.OrderBy = "desc";
            model.PageIndex = 1;
            model.PageSize = 10;
            model.FieldName1 = "Field1";
            model.FieldName2 = "Field2";
            model.Keywords = keyword;
            model.FieldFilter = field;
            model.LinkParams = string.Format("keyword:{0}-field:{1}", model.Keywords, model.FieldFilter);

            // Get all leads
            lmRepository.GetModel(ref model);

            return View(model);
        }

        [HttpPost]
        public ActionResult Filters(string userId, string statusId, string sourceId, string startDate, string endDate, int pageIndex, int pageSize, string sortBy, string orderBy, int leadId, int assignId)
        {
            LeadViewModel model = new LeadViewModel();

            // Setup model
            model.PageType = "Menu";
            SetupCommon(model, string.Empty, "Name");

            // split date
            if (!string.IsNullOrEmpty(startDate))
            {
                string[] arr1 = startDate.Split('/');
                model.StartDate =  string.Format("{0}-{1}-{2}", arr1[2], arr1[1], arr1[0]);
            }
            if (!string.IsNullOrEmpty(endDate))
            {
                string[] arr2 = endDate.Split('/');
                model.EndDate = string.Format("{0}-{1}-{2}", arr2[2], arr2[1], arr2[0]); 
            }

            // Build params
            model.UserId = userId;
            model.StatusId = statusId;
            model.LeadSourceId = sourceId;
            model.SortBy = sortBy;
            model.OrderBy = orderBy;
            model.PageIndex = pageIndex;
            model.PageSize = pageSize;
            model.FieldName1 = "Field1";
            model.FieldName2 = "Field2";
            model.LinkParams = string.Format("uid:{0}-sid:{1}-lid:{2}-start:{3}-end:{4}-page:{5}-size:{6}-sort:{7}-order:{8}", model.UserId, model.StatusId, model.LeadSource, model.StartDate, model.EndDate, model.PageIndex, model.PageSize, model.SortBy.ToLower(), model.OrderBy);
            
            if (leadId > 0 && assignId > 0)
            {
                // Reassign a lead
                repository.ReassignLead(leadId, assignId);
            }
            else if (leadId > 0)
            {
                // Delete a lead
                repository.DeleteLead(leadId);
                model.PageIndex = 1;
            }

            // Get all leads
            lmRepository.GetModel(ref model);

            return Json(model, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult FindFilters(string keywords, string field, int pageIndex, int pageSize, string sortBy, string orderBy, int leadId, int assignId)
        {
            LeadViewModel model = new LeadViewModel();

            // Setup model
            model.PageType = "Menu";
            SetupCommon(model, string.Empty, "Name");

            if (model.IsAdmin)
                model.UserId = string.Empty;

            // Build params
            model.Keywords = keywords;
            model.FieldFilter = field;
            model.SortBy = sortBy;
            model.OrderBy = orderBy;
            model.PageIndex = pageIndex;
            model.PageSize = pageSize;
            model.FieldName1 = "Field1";
            model.FieldName2 = "Field2";
            model.LinkParams = string.Format("keyword:{0}-field:{1}", model.Keywords, model.FieldFilter);

            if (leadId > 0 && assignId > 0)
            {
                // Reassign a lead
                repository.ReassignLead(leadId, assignId);
            }
            else if (leadId > 0)
            {
                // Delete a lead
                repository.DeleteLead(leadId);
                model.PageIndex = 1;
            }

            // Get all leads
            lmRepository.GetModel(ref model);

            return Json(model, JsonRequestBehavior.AllowGet);
        }

        #region Add/Edit Lead
        [Authorize(Roles = "Administrator,Registered")]
        public ActionResult Add(int? id, int? sourceId)
        {
            LeadViewModel model = new LeadViewModel();

            // Setup model
            model.PageType = "Leads";
            model.LeadSourceId = (sourceId == null) ? string.Empty : sourceId.ToString();
            model.LeadTypeId = (id == null) ? string.Empty : id.ToString();            
            SetupCommon(model, string.Empty, "Name");
            repository.GetModel(ref model);

            if(model.LeadType!=null && model.LeadType.Count>0)
            {
                // Show only first tab for first load
                if (string.IsNullOrEmpty(model.LeadTypeId) && model.ListTab != null && model.ListTab.Count > 0)
                {
                    List<FieldGroupInfo> list = new List<FieldGroupInfo>();
                    list.Add(model.ListTab[0]);
                    model.ListTab = list;
                }
                else
                {
                    // Show all common fields and only fields that depend leadformtype
                    repository.ClearInputTags(ref model, int.Parse(model.LeadTypeId));
                }
            }

            return View(model);
        }

        [HttpPost]
        [ValidateInput(false)]
        [Authorize(Roles = "Administrator, Registered")]
        public ActionResult Add(int?id, FormCollection form)
        { 
            int userId = int.Parse(form["User"].ToString());
            int statusId = 1;
            int leadFormTypeId = int.Parse(form["LeadType"].ToString());
            int leadSourceId = int.Parse(form["LeadSource"].ToString());
            int milestoneId = 1;
            int lastActionTypeId = 0;

            // Create a new lead
            int leadId = repository.Create(userId, statusId, leadSourceId, milestoneId, lastActionTypeId, leadFormTypeId, form);

            return Redirect(string.Format("/Lead/Edit/{0}?query=new", leadId));
        }

        [Authorize(Roles = "Administrator,Registered")]
        public ActionResult Edit(int id, string query, int? leadType)
        {
            LeadViewModel model = new LeadViewModel();

            // Setup model
            if (!string.IsNullOrEmpty(query) && query.ToUpper() == "NEW")
                model.NewLead = true;

            SetupCommon(model, string.Empty, "Name");
            model.PageType = "Leads";
            model.LeadId = id;          

            // Ignore lead
            if (!string.IsNullOrEmpty(query))
            {
                bool ignored = false;
                if (bool.TryParse(query, out ignored))
                {
                    NotificationResponseLog log=new NotificationResponseLog();
                    NotificationResponseLogRepository noticeRepository = new NotificationResponseLogRepository();
                    log = noticeRepository.GetSingleByLeadId(id);
                    if (log != null)
                    {
                        log.Response = true;
                        noticeRepository.Update(log);
                    }
                }
            }

            repository.GetModel(ref model, id);

            if (leadType != null && leadType.Value > 0)
            {
                model.LeadTypeId = leadType.Value.ToString();
                repository.ClearInputTags(ref model, int.Parse(model.LeadTypeId));
            }

            if (model.OwnerId == "0")
            {
                model.UserFilter.Add(new ItemFilter() { ID = "0", ItemName = "Chưa được gán" });
            }

            // Get role for user
            if (provider.IsUserInRoleExtend(User.Identity.Name, "Registered"))
            {
                model.UserId = new UserRepository().GetSingle(User.Identity.Name).ID.ToString();
                if (model.UserId != model.OwnerId)
                    Response.Redirect("/Error");
            }

            // Get next / prev links
                        
            return View(model);
        }

        [HttpPost]
        public ActionResult AddStatus(int id, int userId, int statusId, string note)
        {
            LeadViewModel model = new LeadViewModel();

            // Add status log
            LeadStatusLogRepository logRepository = new LeadStatusLogRepository();
            LeadStatusLog log = new LeadStatusLog();
            log.Hidden = false;
            log.LeadId = id;
            log.LogDate = DateTime.Now;
            log.Note = note;
            log.StatusId = statusId;
            log.UserId = userId;
            logRepository.Create(log);

            // Update actions 
            // repository.Update(id, statusId);

            // Update milestone/action
            var status = new LeadStatusRepository().GetSingle(statusId);
            if (status!=null)
            {
                model.Status = status.Title;
                repository.UpdateLeadMilestone(id, statusId, status.MilestoneId); 
            }

            // Get all status log
            model.StatusLogList = repository.GetAllLeadStatusLogItems(id);

            return Json(model, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult AddCalendar(int leadId, int userId, string subject, string startDate, string startTime, string duration, string reminder)
        {
            LeadAppointmentsModel model = new LeadAppointmentsModel();

            // Add status log
            CalendarItemRepository ciRepository=new CalendarItemRepository();
            CalendarItem item = new CalendarItem();
            item.CreateDate = DateTime.Now;
            item.CreatedByUserId = userId;
            item.Descr = string.Empty;
            item.DurationMins = int.Parse(duration);
            item.IsCompleted = false;
            item.LeadId = leadId;
            item.ReminderMins = int.Parse(reminder.Replace(" minutes", string.Empty));
            string[] arr = startDate.Split('/');
            string date = string.Format("{0}-{1}-{2} {3}", arr[2], arr[1], arr[0], startTime);
            item.StartDate = DateTime.Parse(date);
            item.Title = subject;
            item.UserId = userId;
            ciRepository.Create(item);

            // Get all calendar items log
            LeadCalendarItemRepository leadRepository = new LeadCalendarItemRepository();
            model.ListAppointments = new LeadAppointmentRepository().GetAllAppointmentByLead(leadId);

            return Json(model, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult EditCalendar(int id, int leadId, int userId, string subject, string startDate, string startTime, string duration, string reminder)
        {
            LeadAppointmentsModel model = new LeadAppointmentsModel();

            // Add status log
            CalendarItemRepository ciRepository = new CalendarItemRepository();
            CalendarItem item = ciRepository.GetSingle(id);

            item.CreatedByUserId = userId;
            item.Descr = string.Empty;
            item.IsCompleted = false;
            item.DurationMins = int.Parse(duration);
            item.ReminderMins = int.Parse(reminder.Replace(" minutes", string.Empty));
            string[] arr = startDate.Split('/');
            string date = string.Format("{0}-{1}-{2} {3}", arr[2], arr[1], arr[0], startTime);
            item.StartDate = DateTime.Parse(date);
            item.Title = subject;
            item.UserId = userId;
            ciRepository.Update(item);

            // Get all calendar items log
            LeadCalendarItemRepository leadRepository = new LeadCalendarItemRepository();
            model.ListAppointments = new LeadAppointmentRepository().GetAllAppointmentByLead(leadId);

            return Json(model, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult DeleteCalendar(int id)
        {
            LeadAppointmentsModel model = new LeadAppointmentsModel();

            // Add status log
            CalendarItemRepository ciRepository = new CalendarItemRepository();
            ciRepository.Delete(id);

            return Json(string.Empty, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        [ValidateInput(false)]
        [Authorize(Roles = "Administrator, Registered")]
        public ActionResult Edit(int id, FormCollection form)
        {
            int userId = int.Parse(form["User"].ToString());
            int leadSourceId = int.Parse(form["LeadSource"].ToString());
            int leadTypeId = int.Parse(form["LeadType"].ToString());

            // Update lead
            repository.Update(id, userId, leadSourceId, leadTypeId, form);

            return Redirect("/Lead");
        }

        // Print
        [Authorize(Roles = "Administrator,Registered")]
        public ActionResult PrintLead(int id)
        {
            LeadViewModel model = new LeadViewModel();

            // Setup model
            model.PageType = "Leads";
            model.LeadId = id;
            SetupCommon(model, string.Empty, "Name");
            repository.GetModelPrint(ref model, id);

            // Get lead source name
            var source = new LeadSourceRepository().GetSingle(int.Parse(model.LeadSourceId));
            if (source != null)
            {
                model.LeadSourceTitle = source.Title;
            }

            // Get lead status name
            var status = new LeadStatusRepository().GetSingle(int.Parse(model.StatusId));
            if (status != null)
            {
                model.LeadStatusName = status.Title;
            }

            // Get lead owner name
            var user = new UserRepository().GetSingle(int.Parse(model.UserId));
            if (user != null)
            {
                model.User = string.Format("{0} {1}", user.FirstName, user.LastName);
            }

            return View(model);
        }
        #endregion

        #region Notification
        [HttpPost]
        public ActionResult Notification(int userId)
        {
            NotificationResponseLogRepository repository = new NotificationResponseLogRepository();
            int LeadId = 0;

            LeadId = repository.GetLeadId(userId);

            return Json(LeadId, JsonRequestBehavior.AllowGet);
        }
        
        [HttpPost]
        public ActionResult IgnoreNotification(int userId)
        {
            try
            {
                lmRepository.IgnoreLeadNotification(userId);
            }
            catch
            {
            }
            return Json(string.Empty, JsonRequestBehavior.AllowGet);
        }

        // Calendar Events
        [HttpPost]
        public ActionResult GetCalendarReminder(int userId)
        {
            LeadCalendarItemRepository repository = new LeadCalendarItemRepository();
            CalendarReminderItem model = new CalendarReminderItem();
            model = repository.GetCaledarReminder(userId);

            return Json(model, JsonRequestBehavior.AllowGet);
        }
        [HttpPost]
        public ActionResult DimissCalendarReminder(int id)
        {
            CalendarItemRepository repository = new CalendarItemRepository();
            CalendarItem model = new CalendarItem();
            model = repository.GetSingle(id);

            if (model != null)
            {
                model.IsCompleted = true;
                repository.Update(model);
            }

            return Json(string.Empty, JsonRequestBehavior.AllowGet);
        }
        #endregion
    }
}
